package com.duomi.lang;

import com.duomi.lang.Functions.*;

import java.io.File;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Constants {

    public static final Map<String, DuomiFunction> BuiltinFunctions = new HashMap<String, DuomiFunction>() {{
        put(">=", new CompareFunc(value -> value >= 0));
        put(">", new CompareFunc(value -> value > 0));
        put("==", new CompareFunc(value -> value == 0));
        put("<=", new CompareFunc(value -> value <= 0));
        put("<", new CompareFunc(value -> value < 0));

        put("and", new BoolLogicFunc(BoolOperator.And));
        put("or", new BoolLogicFunc(BoolOperator.Or));
        put("not", new BoolLogicFunc(BoolOperator.Not));

        put("add", new MathFunc(MathOperator.ADD));
        put("sub", new MathFunc(MathOperator.SUB));
        put("mul", new MathFunc(MathOperator.MULTI));
        put("div", new MathFunc(MathOperator.DIVIDE));
        put("mod", new MathFunc(MathOperator.MOD));

        put("print", new PrintFunction());
        put("println", new PrintlnFunction());

        put("instanceOf", new InstanceOfFunc());

        put("dict", new DictFunc());
        put("list", new ListFunc());
        put("hashSet", new HashSetFunc());
        put("assert", new AssertFunction());

        put("bool?", new BoolFunction());
    }};

    public static final List<Class<?>> BuiltinClasses = new ArrayList<>(Arrays.asList(
            Object.class,

            Math.class,
            Class.class,
            Date.class,
            System.class,
            Thread.class,
            Runtime.class,
            Random.class,
            Process.class,

            Pattern.class,
            Matcher.class,

            File.class,

            String.class,
            Character.class,
            Boolean.class,
            Byte.class,
            Integer.class,
            Long.class,
            Float.class,
            Double.class,
            Number.class,

            StringBuilder.class,
            Collections.class,
            Arrays.class,

            List.class,
            LinkedList.class,
            ArrayList.class,

            Map.class,
            HashMap.class,
            LinkedHashMap.class,

            Set.class,
            HashSet.class,
            LinkedHashSet.class));

    private static final Map<String, Class<?>> sClassCache = new HashMap<>();

    static Class<?> findClass(String name) {
        if (sClassCache.containsKey(name)) {
            return sClassCache.get(name);
        }

        for (Class<?> clz : BuiltinClasses) {
            if (clz.getSimpleName().equals(name)) {
                sClassCache.put(name, clz);
                return clz;
            }
        }

        try {
            final Class<?> clz = Class.forName(name);
            sClassCache.put(name, clz);
            return clz;
        } catch (ClassNotFoundException e) {
            throw new DuomiEvalException("", e);
        }
    }

    static final Set<String> Keywords = new HashSet<>(Arrays.asList(
            "set!",
            "fn",
            "let",
            "new",
            "if",
            "cond",
            "for"
    ));

    private Constants() {
    }


}
